﻿#include "EditView.h"

EditView::EditView(QgsMapCanvas* canvas, QObject* parent)
	: QgsMapTool(canvas), mpCanvas(canvas), mCurrentLayer(nullptr), mEditMode(None), mpRubberBand(nullptr) {
	setAction(nullptr);
}

// 设置当前编辑图层
void EditView::setLayer(QgsVectorLayer* layer, EditMode mode) {
	mCurrentLayer = layer;
	mEditMode = mode;
	points.clear();  // 清空用于线段的点列表

	// 创建橡皮筋对象用于绘制动态线段
	if (mpRubberBand) {
		delete mpRubberBand;
	}
	Qgis::GeometryType geometryType = (mode == PolygonMode) ? Qgis::GeometryType::Polygon : Qgis::GeometryType::Line;
	mpRubberBand = new QgsRubberBand(mpCanvas, Qgis::GeometryType::Line);
	mpRubberBand->setColor(Qt::black);  // 设置橡皮筋的颜色
	mpRubberBand->setWidth(2);        // 设置橡皮筋的宽度

	if (mode == PolygonMode) {
		// 创建自定义符号并应用到橡皮筋
		QgsFillSymbol* symbol = QgsFillSymbol::createSimple({ {"color", "0,255,0,50"},  // 50% 透明度绿色填充
															{"outline_color", "lightgreen"}, // 绿色边界
															{"outline_width", "0.4"} });
		mpRubberBand->setSymbol(symbol);  // 应用自定义符号
	}
	else {
		mpRubberBand->setColor(Qt::black);  // 线段颜色
	}
	mpRubberBand->setWidth(2);  // 设置橡皮筋宽度
}

// 重置编辑状态
void EditView::reset() {
	points.clear();  // 清空点击的点
	if (mpRubberBand) {
		mpRubberBand->reset(Qgis::GeometryType::Line);  // 重置橡皮筋
	}
	mEditMode = None;  // 重置编辑模式
}

// 捕获鼠标点击事件，用于记录点坐标
void EditView::canvasReleaseEvent(QgsMapMouseEvent* event) {
	if (!mCurrentLayer) {
		QMessageBox::warning(nullptr, tr("错误"), tr("未选中图层，无法添加要素！"));
		return;
	}

	if (!mCurrentLayer->isEditable()) {
		if (!mCurrentLayer->startEditing()) {
			QMessageBox::warning(nullptr, tr("错误"), tr("无法进入编辑模式！"));
			return;
		}
	}

	// 根据当前编辑模式进行不同操作
	QgsPointXY mapPoint = event->mapPoint();

	if (mEditMode == PointMode) {
		createPoint(mapPoint);
	}
	else if (mEditMode == LineMode) {
		addPointToLine(mapPoint);
	}
	if (mEditMode == PolygonMode) {
		addPointToPolygon(mapPoint);
	}
}

// 捕获鼠标移动事件，用于更新橡皮筋位置
void EditView::canvasMoveEvent(QgsMapMouseEvent* event) {
	if (mEditMode == LineMode && !points.isEmpty()) {
		QgsPointXY mapPoint = event->mapPoint();
		updateRubberBand(mapPoint);
	}
	else if (mEditMode == PolygonMode && !points.isEmpty()) {
		QgsPointXY mapPoint = event->mapPoint();
		updateRubberBand(mapPoint);  // 更新橡皮筋动态效果
	}
}

// 捕获鼠标双击事件，用于结束线段绘制
void EditView::canvasDoubleClickEvent(QgsMapMouseEvent* event) {
	if (mEditMode == LineMode) {
		finishLine();  // 双击完成线段
	}
	else if (mEditMode == PolygonMode) {
		finishPolygon();  // 双击完成面绘制
	}
}

// 创建点要素
void EditView::createPoint(const QgsPointXY& point) {
	QgsFeature feature(mCurrentLayer->fields());
	feature.setGeometry(QgsGeometry::fromPointXY(point));

	// 初始化属性
	initializeAttributes(feature);

	if (mCurrentLayer->addFeature(feature)) {
		mpCanvas->refresh();
	}
	else {
		QMessageBox::warning(nullptr, tr("错误"), tr("无法添加要素！"));
	}
}

// 添加点到线段列表
void EditView::addPointToLine(const QgsPointXY& point) {
	points.append(point);  // 将点击的点添加到线段的点列表

	// 更新橡皮筋，添加新的顶点
	mpRubberBand->addPoint(point, true);
}

// 更新橡皮筋的动态效果
void EditView::updateRubberBand(const QgsPointXY& tempPoint) {
	mpRubberBand->removeLastPoint();  // 移除上一个动态点
	mpRubberBand->addPoint(tempPoint, true);  // 添加当前鼠标位置为动态点
}

// 完成线要素的创建
void EditView::finishLine() {
	if (points.size() < 2) {
		QMessageBox::warning(nullptr, tr("错误"), tr("线段必须至少包含两个点！"));
		return;
	}

	QgsPolylineXY polyline;
	for (const QgsPointXY& point : points) {
		polyline.push_back(point);  // 将QList中的点逐个添加到vector中
	}

	QgsFeature feature(mCurrentLayer->fields());
	feature.setGeometry(QgsGeometry::fromPolylineXY(polyline));  // 使用转换后的 polyline

	// 初始化属性
	initializeAttributes(feature);

	if (mCurrentLayer->addFeature(feature)) {
		mpCanvas->refresh();
	}
	else {
		QMessageBox::warning(nullptr, tr("错误"), tr("无法添加要素！"));
	}

	reset();  // 清空当前线创建状态
}

// 添加点到面顶点列表
void EditView::addPointToPolygon(const QgsPointXY& point) {
	points.append(point);  // 将点击的点添加到面顶点列表

	// 更新橡皮筋，添加新的顶点
	mpRubberBand->addPoint(point, true);
}

// 完成面要素的创建
void EditView::finishPolygon() {
	if (points.size() < 3) {
		QMessageBox::warning(nullptr, tr("错误"), tr("面必须至少包含三个点！"));
		return;
	}

	// 创建 QgsPolygonXY (QList<QgsPointXY> 的列表)
	QgsPolygonXY polygon;
	QgsPolylineXY ring;
	for (const QgsPointXY& point : points) {
		ring.push_back(point);
	}
	polygon.push_back(ring);  // 添加闭合的环作为面

	// 创建要素并设置几何
	QgsFeature feature(mCurrentLayer->fields());
	feature.setGeometry(QgsGeometry::fromPolygonXY(polygon));  // 创建面几何

	// 初始化属性
	initializeAttributes(feature);

	if (mCurrentLayer->addFeature(feature)) {
		mpCanvas->refresh();  // 刷新地图画布
		mCurrentLayer->triggerRepaint();  // 强制图层重新渲染，确保应用样式
	}
	else {
		QMessageBox::warning(nullptr, tr("错误"), tr("无法添加要素！"));
	}

	reset();  // 清空当前面创建状态
}

// 初始化要素的属性字段
void EditView::initializeAttributes(QgsFeature& feature) {
	const QgsFields& fields = mCurrentLayer->fields();
	for (int i = 0; i < fields.count(); ++i) {
		const QgsField& field = fields.at(i);
		if (field.type() == QVariant::Int) {
			feature.setAttribute(i, 0);  // 整数类型字段默认值为 0
		}
		else if (field.type() == QVariant::Double) {
			feature.setAttribute(i, 0.0);  // 浮点数类型字段默认值为 0.0
		}
		else if (field.type() == QVariant::String) {
			feature.setAttribute(i, "");  // 字符串类型字段默认值为空字符串
		}
		else if (field.type() == QVariant::Bool) {
			feature.setAttribute(i, false);  // 布尔类型字段默认值为 false
		}
		else {
			feature.setAttribute(i, QVariant());  // 其他类型，使用无值
		}
	}
};
